package routing.googleadapter;

import java.io.IOException;
import java.io.StringReader;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import de.rose_mobil.models.Coordinates;
import de.rose_mobil.models.route.Waypoint;



/**
 * represents a KML-file from Google and is able to parse it
 * into a vector of Placemarks and to a JSON string
 * 
 * @author Alexander Münch (sialmuen)
 */
public class KmlParser extends DefaultHandler {
	
	private String kmlData;
	private Vector<Waypoint> waypoints;
	
	/**
	 * @param xmlKmlData: full XML data
	 */
	public KmlParser(String xmlKmlData) {
		kmlData = xmlKmlData;
		waypoints = null;
	}

	
	/**
	 * returns a vector of KmlPlacemarks
	 * @return Vector of KmlPlacemarks
	 */
	public Vector<Waypoint> getWaypoints(){
		if(waypoints == null)
			parse();
		
		return waypoints;
	}
	
	
	/**
	 * parses the data
	 */
	private void parse() {		
		DocumentBuilder dBuilder;
		Document document;
		
		waypoints = new Vector<Waypoint>();

		try {
			dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			document = dBuilder.parse(new InputSource(new StringReader(kmlData)));
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}

		NodeList placemarkNodes = document.getElementsByTagName("step");
		for(int i = 0; i < placemarkNodes.getLength(); i++) {
			Node placemarkNode = placemarkNodes.item(i);

			String name = "";
			String description = "";
			Coordinates coordinates = null;
			Waypoint start = null;

			if(placemarkNode.hasChildNodes()) {
				Node child = placemarkNode.getFirstChild();
				do {
					String tagName = child.getNodeName();

					if(tagName.equals("start_location")) {
						name = "step_start";
						coordinates = getCoordinates(child.getFirstChild());
						waypoints.add(start = new Waypoint(name, "N�chste Anweisung", coordinates));

					}
					else if(tagName.equals("end_location")) {
						name = "step_end";
						coordinates = getCoordinates(child.getFirstChild());
						waypoints.add(new Waypoint(name, "Zwischenziel erreicht", coordinates));
					}
					else if(tagName.equals("html_instructions")) {
						description = child.getTextContent();
						if (start != null) start.setMessage(description);
					} 

					child = child.getNextSibling();
				} while(child != null);
			}

		}	
	}
	
	private Coordinates getCoordinates(Node pointChild) {
		double lat = 0, lng = 0;
		
		while(pointChild != null) {
			if(pointChild.getNodeName().equals("lat")) lat = Double.valueOf(pointChild.getTextContent());
			else if(pointChild.getNodeName().equals("lng")) lng = Double.valueOf(pointChild.getTextContent());

			pointChild = pointChild.getNextSibling();
		}
		
		return new Coordinates(lat, lng);
	}
	/**
	 * returns all waypoints as a JSON array
	 * @return String JSON array
	 */
	public String toJSON() {
		if(waypoints == null)
			parse();
		
		String json = "[";
		
		try {
			for(int i = 0; i < waypoints.size(); i++) {
				json += waypoints.elementAt(i).toJSONObject().toString();

				if(i != waypoints.size() - 1)
					json += ",\n";
			}
		} catch (Exception e) {
			
		}
		
		json += "]";
		return json;
	}
	
	
	/**
	 * debug testing main
	 * 
	 * @param args unused
	 */
	public static void main(String[] args) {
		String xml = GoogleRoutingAdapter.getGoogleRouteAsKML("Pfarrergasse 1,Regensburg", "Von-der-Tann-Stra�e 8 Regensburg");
		KmlParser kml = new KmlParser(xml);
		System.out.println(kml.toJSON());
	}
	
}
